package com.zeta.demo.seata.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zeta.api.client.demo.IDemoSeata2Api;
import com.zeta.api.model.DemoDTO;
import com.zeta.demo.seata.dao.DemoSeataMapper;
import com.zeta.demo.seata.model.entity.DemoSeata;
import com.zeta.demo.seata.service.IDemoSeataService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.zetaframework.base.exception.BusinessException;
import org.zetaframework.base.result.ApiResult;

/**
 * Seata测试 服务实现类
 *
 * @author AutoGenerator
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DemoSeataServiceImpl extends ServiceImpl<DemoSeataMapper, DemoSeata> implements IDemoSeataService {

    private final IDemoSeata2Api demoSeata2Api;

    /**
     * 测试seata
     *
     * @return boolean
     */
    @GlobalTransactional(rollbackFor = Exception.class)
    // @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean testSeata() {
        // 获取数据总条数
        long count = this.count();
        count += 1;

        // 保存数据
        DemoSeata demo = new DemoSeata();
        demo.setName("测试seata" + count);
        demo.setCode("testSeata" + count);
        demo.setDescribe("测试seata" + count);
        if (!this.save(demo)) {
            throw new BusinessException("保存失败！！");
        }

        // 调用seata-demo2-server, 抛出异常，看看DemoSeata表数据是否回滚。 注意：这里并不会总是抛出异常，请多试几次
        ApiResult<Boolean> booleanApiResult = demoSeata2Api.tryException(BeanUtil.toBean(demo, DemoDTO.class));
        if (!booleanApiResult.getSuccess()) {
            // 如果远程调用失败，则抛出异常，回滚DemoSeata表数据
            throw new BusinessException(booleanApiResult.getMessage());
        }
        return true;
    }


    /**
     * 测试异步方法中打印MdcLog
     */
    @Async
    @Override
    public void testMdcLogAsync() {
        log.info("async testMdcLog...");
    }
}
